#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Azure DevOps 认证测试GUI界面
"""

import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext, filedialog
import threading
import os
from azure_devops_client import AzureDevOpsClient


class AzureDevOpsGUI:
    """Azure DevOps 测试GUI界面"""
    
    def __init__(self, root):
        self.root = root
        self.root.title("Azure DevOps 认证测试工具")
        self.root.geometry("800x600")
        
        # 客户端实例
        self.client = None
        
        # 创建界面
        self.create_widgets()
        
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=1)
        
        # 认证配置区域
        auth_frame = ttk.LabelFrame(main_frame, text="认证配置", padding="5")
        auth_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        auth_frame.columnconfigure(1, weight=1)
        
        # 服务器URL
        ttk.Label(auth_frame, text="服务器URL:").grid(row=0, column=0, sticky=tk.W, pady=2)
        self.server_url_var = tk.StringVar(value="https://dev.azure.com")
        ttk.Entry(auth_frame, textvariable=self.server_url_var, width=50).grid(row=0, column=1, sticky=(tk.W, tk.E), pady=2, padx=(5, 0))
        
        # 组织名称
        ttk.Label(auth_frame, text="组织名称:").grid(row=1, column=0, sticky=tk.W, pady=2)
        self.organization_var = tk.StringVar()
        ttk.Entry(auth_frame, textvariable=self.organization_var, width=50).grid(row=1, column=1, sticky=(tk.W, tk.E), pady=2, padx=(5, 0))
        
        # 用户名
        ttk.Label(auth_frame, text="用户名:").grid(row=2, column=0, sticky=tk.W, pady=2)
        self.username_var = tk.StringVar()
        ttk.Entry(auth_frame, textvariable=self.username_var, width=50).grid(row=2, column=1, sticky=(tk.W, tk.E), pady=2, padx=(5, 0))
        
        # PAT令牌
        ttk.Label(auth_frame, text="PAT令牌:").grid(row=3, column=0, sticky=tk.W, pady=2)
        self.pat_token_var = tk.StringVar()
        pat_entry = ttk.Entry(auth_frame, textvariable=self.pat_token_var, width=50, show="*")
        pat_entry.grid(row=3, column=1, sticky=(tk.W, tk.E), pady=2, padx=(5, 0))
        
        # 显示/隐藏PAT按钮
        self.show_pat_var = tk.BooleanVar()
        ttk.Checkbutton(auth_frame, text="显示PAT", variable=self.show_pat_var, 
                       command=self.toggle_pat_visibility).grid(row=3, column=2, pady=2, padx=(5, 0))
        
        # 测试连接按钮
        ttk.Button(auth_frame, text="测试连接", command=self.test_connection).grid(row=4, column=0, columnspan=3, pady=10)
        
        # 功能区域
        func_frame = ttk.LabelFrame(main_frame, text="功能测试", padding="5")
        func_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
        func_frame.columnconfigure(0, weight=1)
        func_frame.rowconfigure(1, weight=1)
        
        # 功能按钮区域
        button_frame = ttk.Frame(func_frame)
        button_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
        
        ttk.Button(button_frame, text="获取项目列表", command=self.get_projects).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(button_frame, text="获取仓库列表", command=self.get_repositories).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(button_frame, text="获取文件列表", command=self.get_repository_items).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(button_frame, text="下载文件", command=self.download_file).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(button_frame, text="克隆仓库", command=self.clone_repository).pack(side=tk.LEFT, padx=(0, 5))
        
        # 结果显示区域
        result_frame = ttk.Frame(func_frame)
        result_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        result_frame.columnconfigure(0, weight=1)
        result_frame.rowconfigure(0, weight=1)
        
        # 结果文本框
        self.result_text = scrolledtext.ScrolledText(result_frame, height=15, width=80)
        self.result_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 状态栏
        self.status_var = tk.StringVar(value="就绪")
        status_bar = ttk.Label(main_frame, textvariable=self.status_var, relief=tk.SUNKEN)
        status_bar.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(10, 0))
        
    def toggle_pat_visibility(self):
        """切换PAT令牌的显示/隐藏"""
        # 这个方法需要重新实现，因为ttk.Entry没有show参数
        pass
        
    def log_message(self, message):
        """在结果区域添加消息"""
        self.result_text.insert(tk.END, f"{message}\n")
        self.result_text.see(tk.END)
        self.root.update()
        
    def update_status(self, message):
        """更新状态栏"""
        self.status_var.set(message)
        self.root.update()
        
    def test_connection(self):
        """测试连接"""
        def test():
            try:
                self.update_status("正在测试连接...")
                self.log_message("开始测试连接...")
                
                # 创建客户端
                self.client = AzureDevOpsClient(
                    organization=self.organization_var.get(),
                    username=self.username_var.get(),
                    pat_token=self.pat_token_var.get(),
                    server_url=self.server_url_var.get()
                )
                
                # 测试连接
                success, message = self.client.test_connection()
                
                if success:
                    self.log_message(f"✓ {message}")
                    self.update_status("连接成功")
                else:
                    self.log_message(f"✗ {message}")
                    self.update_status("连接失败")
                    
            except Exception as e:
                self.log_message(f"✗ 连接测试异常: {str(e)}")
                self.update_status("连接异常")
                
        # 在新线程中执行
        threading.Thread(target=test, daemon=True).start()
        
    def get_projects(self):
        """获取项目列表"""
        if not self.client:
            messagebox.showerror("错误", "请先测试连接")
            return
            
        def get():
            try:
                self.update_status("正在获取项目列表...")
                self.log_message("获取项目列表...")
                
                success, result = self.client.get_projects()
                
                if success:
                    self.log_message("项目列表:")
                    for project in result:
                        self.log_message(f"  - {project['name']} (ID: {project['id']})")
                        self.log_message(f"    描述: {project['description']}")
                    self.update_status("获取项目列表成功")
                else:
                    self.log_message(f"✗ {result}")
                    self.update_status("获取项目列表失败")
                    
            except Exception as e:
                self.log_message(f"✗ 获取项目列表异常: {str(e)}")
                self.update_status("获取项目列表异常")
                
        threading.Thread(target=get, daemon=True).start()
        
    def get_repositories(self):
        """获取仓库列表"""
        if not self.client:
            messagebox.showerror("错误", "请先测试连接")
            return
            
        # 获取项目名称
        project_name = tk.simpledialog.askstring("输入项目名称", "请输入项目名称:")
        if not project_name:
            return
            
        def get():
            try:
                self.update_status("正在获取仓库列表...")
                self.log_message(f"获取项目 '{project_name}' 的仓库列表...")
                
                success, result = self.client.get_repositories(project_name)
                
                if success:
                    self.log_message("仓库列表:")
                    for repo in result:
                        self.log_message(f"  - {repo['name']} (ID: {repo['id']})")
                        self.log_message(f"    默认分支: {repo['defaultBranch']}")
                        self.log_message(f"    远程URL: {repo['remoteUrl']}")
                    self.update_status("获取仓库列表成功")
                else:
                    self.log_message(f"✗ {result}")
                    self.update_status("获取仓库列表失败")
                    
            except Exception as e:
                self.log_message(f"✗ 获取仓库列表异常: {str(e)}")
                self.update_status("获取仓库列表异常")
                
        threading.Thread(target=get, daemon=True).start()
        
    def get_repository_items(self):
        """获取仓库文件列表"""
        if not self.client:
            messagebox.showerror("错误", "请先测试连接")
            return
            
        # 获取项目名称和仓库名称
        project_name = tk.simpledialog.askstring("输入项目名称", "请输入项目名称:")
        if not project_name:
            return
            
        repository_name = tk.simpledialog.askstring("输入仓库名称", "请输入仓库名称:")
        if not repository_name:
            return
            
        def get():
            try:
                self.update_status("正在获取文件列表...")
                self.log_message(f"获取仓库 '{repository_name}' 的文件列表...")
                
                success, result = self.client.get_repository_items(project_name, repository_name)
                
                if success:
                    self.log_message("文件列表:")
                    for item in result:
                        item_type = "文件夹" if item['isFolder'] else "文件"
                        size_info = f" ({item['size']} bytes)" if not item['isFolder'] else ""
                        self.log_message(f"  - {item['path']} [{item_type}]{size_info}")
                    self.update_status("获取文件列表成功")
                else:
                    self.log_message(f"✗ {result}")
                    self.update_status("获取文件列表失败")
                    
            except Exception as e:
                self.log_message(f"✗ 获取文件列表异常: {str(e)}")
                self.update_status("获取文件列表异常")
                
        threading.Thread(target=get, daemon=True).start()
        
    def download_file(self):
        """下载文件"""
        if not self.client:
            messagebox.showerror("错误", "请先测试连接")
            return
            
        # 获取参数
        project_name = tk.simpledialog.askstring("输入项目名称", "请输入项目名称:")
        if not project_name:
            return
            
        repository_name = tk.simpledialog.askstring("输入仓库名称", "请输入仓库名称:")
        if not repository_name:
            return
            
        file_path = tk.simpledialog.askstring("输入文件路径", "请输入文件路径 (例如: /src/main.py):")
        if not file_path:
            return
            
        # 选择保存位置
        local_path = filedialog.asksaveasfilename(
            title="选择保存位置",
            defaultextension="",
            filetypes=[("所有文件", "*.*")]
        )
        if not local_path:
            return
            
        def download():
            try:
                self.update_status("正在下载文件...")
                self.log_message(f"下载文件: {file_path}")
                
                success, result = self.client.download_file(project_name, repository_name, file_path, local_path)
                
                if success:
                    self.log_message(f"✓ {result}")
                    self.update_status("文件下载成功")
                else:
                    self.log_message(f"✗ {result}")
                    self.update_status("文件下载失败")
                    
            except Exception as e:
                self.log_message(f"✗ 下载文件异常: {str(e)}")
                self.update_status("下载文件异常")
                
        threading.Thread(target=download, daemon=True).start()
        
    def clone_repository(self):
        """克隆仓库"""
        if not self.client:
            messagebox.showerror("错误", "请先测试连接")
            return
            
        # 获取参数
        repository_url = tk.simpledialog.askstring("输入仓库URL", "请输入仓库URL:")
        if not repository_url:
            return
            
        branch = tk.simpledialog.askstring("输入分支名称", "请输入分支名称 (默认: main):") or "main"
        
        # 选择保存位置
        local_path = filedialog.askdirectory(title="选择保存目录")
        if not local_path:
            return
            
        # 添加仓库名称到路径
        repo_name = repository_url.split('/')[-1].replace('.git', '')
        local_path = os.path.join(local_path, repo_name)
        
        def clone():
            try:
                self.update_status("正在克隆仓库...")
                self.log_message(f"克隆仓库: {repository_url}")
                self.log_message(f"分支: {branch}")
                self.log_message(f"保存到: {local_path}")
                
                success, result = self.client.clone_repository(repository_url, local_path, branch)
                
                if success:
                    self.log_message(f"✓ {result}")
                    self.update_status("仓库克隆成功")
                else:
                    self.log_message(f"✗ {result}")
                    self.update_status("仓库克隆失败")
                    
            except Exception as e:
                self.log_message(f"✗ 克隆仓库异常: {str(e)}")
                self.update_status("克隆仓库异常")
                
        threading.Thread(target=clone, daemon=True).start()


def main():
    """主函数"""
    root = tk.Tk()
    app = AzureDevOpsGUI(root)
    
    # 添加导入
    import tkinter.simpledialog
    
    root.mainloop()


if __name__ == "__main__":
    main()
